// Copyright Epic Games, Inc. All Rights Reserved.

#include "CommonInputBaseTypes.h"
#include "DataSource/GameSettingDataSource.h"
#include "GameSettingCollection.h"
#include "GameSettingValueDiscreteDynamic.h"
#include "GameSettingValueScalarDynamic.h"
#include "LyraGameSettingRegistry.h"
#include "LyraSettingsLocal.h"
#include "LyraSettingsShared.h"
#include "NativeGameplayTags.h"
#include "Player/LyraLocalPlayer.h"

#define LOCTEXT_NAMESPACE "Lyra"

// 定义平台特性标签
UE_DEFINE_GAMEPLAY_TAG_STATIC(TAG_Platform_Trait_Input_SupportsGamepad, "Platform.Trait.Input.SupportsGamepad"); // 支持游戏手柄输入平台特性标签
UE_DEFINE_GAMEPLAY_TAG_STATIC(TAG_Platform_Trait_Input_SupportsTriggerHaptics, "Platform.Trait.Input.SupportsTriggerHaptics"); // 支持扳机触觉反馈平台特性标签

/**
 * 初始化游戏手柄设置
 * @param InLocalPlayer 本地玩家
 * @return 游戏设置集合
 */
UGameSettingCollection* ULyraGameSettingRegistry::InitializeGamepadSettings(ULyraLocalPlayer* InLocalPlayer)
{
	UGameSettingCollection* Screen = NewObject<UGameSettingCollection>(); // 创建游戏设置集合
	Screen->SetDevName(TEXT("GamepadCollection")); // 设置开发名称
	Screen->SetDisplayName(LOCTEXT("GamepadCollection_Name", "Gamepad")); // 设置显示名称
	Screen->Initialize(InLocalPlayer); // 初始化

	// 硬件
	////////////////////////////////////////////////////////////////////////////////////
	{
		UGameSettingCollection* Hardware = NewObject<UGameSettingCollection>(); // 创建硬件设置集合
		Hardware->SetDevName(TEXT("HardwareCollection")); // 设置开发名称
		Hardware->SetDisplayName(LOCTEXT("HardwareCollection_Name", "Hardware")); // 设置显示名称
		Screen->AddSetting(Hardware); // 添加到屏幕设置
			
		//----------------------------------------------------------------------------------
		{
			UGameSettingValueDiscreteDynamic* Setting = NewObject<UGameSettingValueDiscreteDynamic>(); // 创建离散动态值设置
			Setting->SetDevName(TEXT("ControllerHardware")); // 设置开发名称
			Setting->SetDisplayName(LOCTEXT("ControllerHardware_Name", "Controller Hardware")); // 设置显示名称
			Setting->SetDescriptionRichText(LOCTEXT("ControllerHardware_Description", "The type of controller you're using.")); // 设置描述富文本
			Setting->SetDynamicGetter(GET_LOCAL_SETTINGS_FUNCTION_PATH(GetControllerPlatform)); // 设置动态获取器
			Setting->SetDynamicSetter(GET_LOCAL_SETTINGS_FUNCTION_PATH(SetControllerPlatform)); // 设置动态设置器
			
			if (UCommonInputPlatformSettings* PlatformInputSettings = UPlatformSettingsManager::Get().GetSettingsForPlatform<UCommonInputPlatformSettings>()) // 如果获取到通用输入平台设置
			{
				const TArray<TSoftClassPtr<UCommonInputBaseControllerData>>& ControllerDatas = PlatformInputSettings->GetControllerData(); // 获取控制器数据
				for (TSoftClassPtr<UCommonInputBaseControllerData> ControllerDataPtr : ControllerDatas) // 遍历控制器数据
				{
					if (TSubclassOf<UCommonInputBaseControllerData> ControllerDataClass = ControllerDataPtr.LoadSynchronous()) // 如果同步加载控制器数据类成功
					{
						const UCommonInputBaseControllerData* ControllerData = ControllerDataClass.GetDefaultObject(); // 获取控制器数据默认对象
						if (ControllerData->InputType == ECommonInputType::Gamepad) // 如果是游戏手柄输入类型
						{
							Setting->AddDynamicOption(ControllerData->GamepadName.ToString(), ControllerData->GamepadDisplayName); // 添加动态选项
						}
					}
				}

				// 如果此平台上可以选择多个游戏控制器类型并且允许更改，则添加设置
				if (Setting->GetDynamicOptions().Num() > 1 && PlatformInputSettings->CanChangeGamepadType()) // 如果动态选项数量大于1且可以更改游戏手柄类型
				{
					Hardware->AddSetting(Setting); // 添加到硬件设置

					const FName CurrentControllerPlatform = GetDefault<ULyraSettingsLocal>()->GetControllerPlatform(); // 获取当前控制器平台
					if (CurrentControllerPlatform == NAME_None) // 如果当前控制器平台为空
					{
						Setting->SetDiscreteOptionByIndex(0); // 按索引设置离散选项
					}
					else
					{
						Setting->SetDefaultValueFromString(CurrentControllerPlatform.ToString()); // 从字符串设置默认值
					}
				}
			}
		}
		//----------------------------------------------------------------------------------
		{
			UGameSettingValueDiscreteDynamic_Bool* Setting = NewObject<UGameSettingValueDiscreteDynamic_Bool>(); // 创建布尔离散值设置
			Setting->SetDevName(TEXT("GamepadVibration")); // 设置开发名称
			Setting->SetDisplayName(LOCTEXT("GamepadVibration_Name", "Vibration")); // 设置显示名称
			Setting->SetDescriptionRichText(LOCTEXT("GamepadVibration_Description", "Turns controller vibration on/off.")); // 设置描述富文本

			Setting->SetDynamicGetter(GET_SHARED_SETTINGS_FUNCTION_PATH(GetForceFeedbackEnabled)); // 设置动态获取器
			Setting->SetDynamicSetter(GET_SHARED_SETTINGS_FUNCTION_PATH(SetForceFeedbackEnabled)); // 设置动态设置器
			Setting->SetDefaultValue(GetDefault<ULyraSettingsShared>()->GetForceFeedbackEnabled()); // 设置默认值

			Hardware->AddSetting(Setting); // 添加到硬件设置
		}
		//----------------------------------------------------------------------------------
		{
			UGameSettingValueDiscreteDynamic_Bool* Setting = NewObject<UGameSettingValueDiscreteDynamic_Bool>(); // 创建布尔离散值设置
			Setting->SetDevName(TEXT("InvertVerticalAxis_Gamepad")); // 设置开发名称
			Setting->SetDisplayName(LOCTEXT("InvertVerticalAxis_Gamepad_Name", "Invert Vertical Axis")); // 设置显示名称
			Setting->SetDescriptionRichText(LOCTEXT("InvertVerticalAxis_Gamepad_Description", "Enable the inversion of the vertical look axis.")); // 设置描述富文本

			Setting->SetDynamicGetter(GET_SHARED_SETTINGS_FUNCTION_PATH(GetInvertVerticalAxis)); // 设置动态获取器
			Setting->SetDynamicSetter(GET_SHARED_SETTINGS_FUNCTION_PATH(SetInvertVerticalAxis)); // 设置动态设置器
			Setting->SetDefaultValue(GetDefault<ULyraSettingsShared>()->GetInvertVerticalAxis()); // 设置默认值

			Hardware->AddSetting(Setting); // 添加到硬件设置
		}
		//----------------------------------------------------------------------------------
		{
			UGameSettingValueDiscreteDynamic_Bool* Setting = NewObject<UGameSettingValueDiscreteDynamic_Bool>(); // 创建布尔离散值设置
			Setting->SetDevName(TEXT("InvertHorizontalAxis_Gamepad")); // 设置开发名称
			Setting->SetDisplayName(LOCTEXT("InvertHorizontalAxis_Gamepad_Name", "Invert Horizontal Axis")); // 设置显示名称
			Setting->SetDescriptionRichText(LOCTEXT("InvertHorizontalAxis_Gamepad_Description", "Enable the inversion of the Horizontal look axis.")); // 设置描述富文本

			Setting->SetDynamicGetter(GET_SHARED_SETTINGS_FUNCTION_PATH(GetInvertHorizontalAxis)); // 设置动态获取器
			Setting->SetDynamicSetter(GET_SHARED_SETTINGS_FUNCTION_PATH(SetInvertHorizontalAxis)); // 设置动态设置器
			Setting->SetDefaultValue(GetDefault<ULyraSettingsShared>()->GetInvertHorizontalAxis()); // 设置默认值

			Hardware->AddSetting(Setting); // 添加到硬件设置
		}
		//----------------------------------------------------------------------------------
	}

	////////////////////////////////////////////////////////////////////////////////////
	{
		UGameSettingCollection* GamepadBinding = NewObject<UGameSettingCollection>(); // 创建游戏手柄绑定设置集合
		GamepadBinding->SetDevName(TEXT("GamepadBindingCollection")); // 设置开发名称
		GamepadBinding->SetDisplayName(LOCTEXT("GamepadBindingCollection_Name", "Controls")); // 设置显示名称
		Screen->AddSetting(GamepadBinding); // 添加到屏幕设置
	}

	// 基础 - 视角灵敏度
	////////////////////////////////////////////////////////////////////////////////////
	{
		UGameSettingCollection* BasicSensitivity = NewObject<UGameSettingCollection>(); // 创建基础灵敏度设置集合
		BasicSensitivity->SetDevName(TEXT("BasicSensitivityCollection")); // 设置开发名称
		BasicSensitivity->SetDisplayName(LOCTEXT("BasicSensitivityCollection_Name", "Sensitivity")); // 设置显示名称
		Screen->AddSetting(BasicSensitivity); // 添加到屏幕设置

		// 游戏手柄灵敏度文本数组
		const FText EGamepadSensitivityText[] = {
			FText::GetEmpty(), // 空文本
			LOCTEXT("EFortGamepadSensitivity_Slow", "1 (Slow)"), // 1（慢速）
			LOCTEXT("EFortGamepadSensitivity_SlowPlus", "2 (Slow+)"), // 2（慢速+）
			LOCTEXT("EFortGamepadSensitivity_SlowPlusPlus", "3 (Slow++)"), // 3（慢速++）
			LOCTEXT("EFortGamepadSensitivity_Normal", "4 (Normal)"), // 4（正常）
			LOCTEXT("EFortGamepadSensitivity_NormalPlus", "5 (Normal+)"), // 5（正常+）
			LOCTEXT("EFortGamepadSensitivity_NormalPlusPlus", "6 (Normal++)"), // 6（正常++）
			LOCTEXT("EFortGamepadSensitivity_Fast", "7 (Fast)"), // 7（快速）
			LOCTEXT("EFortGamepadSensitivity_FastPlus", "8 (Fast+)"), // 8（快速+）
			LOCTEXT("EFortGamepadSensitivity_FastPlusPlus", "9 (Fast++)"), // 9（快速++）
			LOCTEXT("EFortGamepadSensitivity_Insane", "10 (Insane)"), // 10（极速）
		};
		
		//----------------------------------------------------------------------------------
		{
			UGameSettingValueDiscreteDynamic_Enum* Setting = NewObject<UGameSettingValueDiscreteDynamic_Enum>(); // 创建枚举离散值设置
			Setting->SetDevName(TEXT("LookSensitivityPreset")); // 设置开发名称
			Setting->SetDisplayName(LOCTEXT("LookSensitivityPreset_Name", "Look Sensitivity")); // 设置显示名称
			Setting->SetDescriptionRichText(LOCTEXT("LookSensitivityPreset_Description", "How quickly your view rotates.")); // 设置描述富文本
			
			Setting->SetDynamicGetter(GET_SHARED_SETTINGS_FUNCTION_PATH(GetGamepadLookSensitivityPreset)); // 设置动态获取器
			Setting->SetDynamicSetter(GET_SHARED_SETTINGS_FUNCTION_PATH(SetLookSensitivityPreset)); // 设置动态设置器
			Setting->SetDefaultValue(GetDefault<ULyraSettingsShared>()->GetGamepadLookSensitivityPreset()); // 设置默认值

			for (int32 PresetIndex = 1; PresetIndex < (int32)ELyraGamepadSensitivity::MAX; PresetIndex++) // 遍历预设索引
			{
				Setting->AddEnumOption(static_cast<ELyraGamepadSensitivity>(PresetIndex), EGamepadSensitivityText[PresetIndex]); // 添加枚举选项
			}
			
			BasicSensitivity->AddSetting(Setting); // 添加到基础灵敏度设置
		}
		//----------------------------------------------------------------------------------
		{
			UGameSettingValueDiscreteDynamic_Enum* Setting = NewObject<UGameSettingValueDiscreteDynamic_Enum>(); // 创建枚举离散值设置
			Setting->SetDevName(TEXT("LookSensitivityPresetAds")); // 设置开发名称
			Setting->SetDisplayName(LOCTEXT("LookSensitivityPresetAds_Name", "Aim Sensitivity (ADS)")); // 设置显示名称
			Setting->SetDescriptionRichText(LOCTEXT("LookSensitivityPresetAds_Description", "How quickly your view rotates while aiming down sights (ADS).")); // 设置描述富文本
			
			Setting->SetDynamicGetter(GET_SHARED_SETTINGS_FUNCTION_PATH(GetGamepadTargetingSensitivityPreset)); // 设置动态获取器
			Setting->SetDynamicSetter(GET_SHARED_SETTINGS_FUNCTION_PATH(SetGamepadTargetingSensitivityPreset)); // 设置动态设置器
			Setting->SetDefaultValue(GetDefault<ULyraSettingsShared>()->GetGamepadTargetingSensitivityPreset()); // 设置默认值

			for (int32 PresetIndex = 1; PresetIndex < (int32)ELyraGamepadSensitivity::MAX; PresetIndex++) // 遍历预设索引
			{
				Setting->AddEnumOption(static_cast<ELyraGamepadSensitivity>(PresetIndex), EGamepadSensitivityText[PresetIndex]); // 添加枚举选项
			}

			BasicSensitivity->AddSetting(Setting); // 添加到基础灵敏度设置
		}
		//----------------------------------------------------------------------------------
	}

	// 死区
	////////////////////////////////////////////////////////////////////////////////////
	{
		UGameSettingCollection* DeadZone = NewObject<UGameSettingCollection>(); // 创建死区设置集合
		DeadZone->SetDevName(TEXT("DeadZoneCollection")); // 设置开发名称
		DeadZone->SetDisplayName(LOCTEXT("DeadZoneCollection_Name", "Controller DeadZone")); // 设置显示名称
		Screen->AddSetting(DeadZone); // 添加到屏幕设置

		//----------------------------------------------------------------------------------
		{
			UGameSettingValueScalarDynamic* Setting = NewObject<UGameSettingValueScalarDynamic>(); // 创建标量动态值设置
			Setting->SetDevName(TEXT("MoveStickDeadZone")); // 设置开发名称
			Setting->SetDisplayName(LOCTEXT("MoveStickDeadZone_Name", "Left Stick DeadZone")); // 设置显示名称
			Setting->SetDescriptionRichText(LOCTEXT("MoveStickDeadZone_Description", "Increase or decrease the area surrounding the stick that we ignore input from.  Setting this value too low may result in the character continuing to move even after removing your finger from the stick.")); // 设置描述富文本

			Setting->SetDynamicGetter(GET_SHARED_SETTINGS_FUNCTION_PATH(GetGamepadMoveStickDeadZone)); // 设置动态获取器
			Setting->SetDynamicSetter(GET_SHARED_SETTINGS_FUNCTION_PATH(SetGamepadMoveStickDeadZone)); // 设置动态设置器
			Setting->SetDefaultValue(GetDefault<ULyraSettingsShared>()->GetGamepadMoveStickDeadZone()); // 设置默认值
			Setting->SetDisplayFormat(UGameSettingValueScalarDynamic::ZeroToOnePercent); // 设置显示格式
			Setting->SetMinimumLimit(0.05); // 设置最小限制
			Setting->SetMaximumLimit(0.95); // 设置最大限制

			DeadZone->AddSetting(Setting); // 添加到死区设置
		}
		//----------------------------------------------------------------------------------
		{
			UGameSettingValueScalarDynamic* Setting = NewObject<UGameSettingValueScalarDynamic>(); // 创建标量动态值设置
			Setting->SetDevName(TEXT("LookStickDeadZone")); // 设置开发名称
			Setting->SetDisplayName(LOCTEXT("LookStickDeadZone_Name", "Right Stick DeadZone")); // 设置显示名称
			Setting->SetDescriptionRichText(LOCTEXT("LookStickDeadZone_Description", "Increase or decrease the area surrounding the stick that we ignore input from.  Setting this value too low may result in the camera continuing to move even after removing your finger from the stick.")); // 设置描述富文本

			Setting->SetDynamicGetter(GET_SHARED_SETTINGS_FUNCTION_PATH(GetGamepadLookStickDeadZone)); // 设置动态获取器
			Setting->SetDynamicSetter(GET_SHARED_SETTINGS_FUNCTION_PATH(SetGamepadLookStickDeadZone)); // 设置动态设置器
			Setting->SetDefaultValue(GetDefault<ULyraSettingsShared>()->GetGamepadLookStickDeadZone()); // 设置默认值
			Setting->SetDisplayFormat(UGameSettingValueScalarDynamic::ZeroToOnePercent); // 设置显示格式
			Setting->SetMinimumLimit(0.05); // 设置最小限制
			Setting->SetMaximumLimit(0.95); // 设置最大限制

			DeadZone->AddSetting(Setting); // 添加到死区设置
		}
		//----------------------------------------------------------------------------------
	}

	return Screen; // 返回屏幕设置集合
}

#undef LOCTEXT_NAMESPACE